<template>
	<view class="gui-img" :id="uid" v-if="lazyLoad">
		<image :src="src" @load="imgLoad" v-if="isLoading&&!isFailed" v-show="showImg" @error="error" :mode="mode"
			class="gui-itemImg" :style="{width:width, height:height, borderRadius:borderRadius}"
			:class="{'showOpacity':showOpacity}"></image>
		<view class="gui-imageLoad" v-show="!showImg&&!isFailed">
			<image class="gui-loadImg" src="/static//loadImg/load.gif" mode="aspectFill"
				:style="{width:width+'rpx', height:height+'rpx', borderRadius:borderRadius}"></image>
		</view>
		<view class="gui-imageLoad" v-if="isFailed">
			<image class="gui-loadImg" src="/static/loadImg/loadfail.png" mode="aspectFill"
				:style="{width:width+'rpx', height:height+'rpx', borderRadius:borderRadius}"></image>
		</view>
	</view>
	<view class="gui-img" v-else>
		<image :src="src" @load="imgLoad" @error="error" :mode="mode" class="gui-itemImg"
			:style="{width:width, height:height, borderRadius:borderRadius}"></image>
		<view class="gui-imageLoad" v-if="isLoading">
			<image class="gui-loadImg" src="/static//loadImg/load.gif" mode="aspectFill"
				:style="{'width': widthIn,
				'height':heightIn, borderRadius:borderRadius}"></image>
		</view>
		<view class="gui-imageLoad" v-if="isFailed">
			<image class="gui-loadImg" src="/static/loadImg/loadfail.png" mode="aspectFill"
				:style="{width:width+'rpx', height:height+'rpx', borderRadius:borderRadius}"></image>
		</view>
	</view>

</template>

<script>
	// 生成全局唯一id
	function generateUUID() {
		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
			let r = Math.random() * 16 | 0,
				v = c == 'x' ? r : (r & 0x3 | 0x8);
			return v.toString(16);
		})
	}
	export default {
		name: "gui-imageLoading",
		computed:{
			widthIn(){
				return this.mode=="heightFix" ? this.height+'rpx': (this.width+'rpx')
			},
			heightIn(){
				return this.mode=="widthFix"?this.width+'rpx':(this.height+'rpx')
			}
		},
		props: {
			src: { //图片路径
				type: String,
				default: ''
			},
			mode: { //图片显示类型
				type: String,
				default: 'aspectFill'
			},
			borderRadius: { //图片圆角
				type: String,
				default: ''
			},
			width: { //图片宽度，默认100%，可设置
				type: String,
				default: '100%'
			},
			height: { //图片高度，默认100%，可设置
				type: String,
				default: '100%'
			},
			lazyLoad: { //是否开启懒加载
				type: Boolean,
				default: false
			},
			scrollTop: { //懒加载滚动高度
				type: Number,
				default: 0
			},
			viewHeight: { //元素高度
				type: Number,
				default () {
					return uni.getSystemInfoSync().windowHeight;
				}
			},
			showOpacity: { //是否开启透明动画
				type: Boolean,
				default: false
			},
		},
		data() {
			return {
				uid: '', //唯一id
				isLoading: false, //是否加载
				showImg: false, //是否显示图片
				isFailed: false, //是否加载错误
			}
		},
		watch: { //懒加载监听滚动
			scrollTop(val) {
				if (!this.lazyLoad) return;
				this.onScroll(val)
			}
		},
		mounted() {
			if (this.lazyLoad) {
				this.isLoading = false
				this.init()
			} else {
				this.isLoading = true
			}
		},
		methods: {
			imgLoad: function(e) {
				if (this.lazyLoad) {
					this.showImg = true;
				} else {
					this.isLoading = false
				}

			},
			error: function(e) {
				if (this.lazyLoad) {
					this.isFailed = true;
				} else {
					this.isLoading = false;
					this.isFailed = true;
				}
			},
			init() {
				this.uid = 'uid-' + generateUUID();
				this.$nextTick(this.onScroll) 
			},
			onScroll(scrollTop) {
				// 加载ing时才执行滚动监听判断是否可加载
				if (this.isLoading || this.isFailed) return;
				const id = this.uid
				const query = uni.createSelectorQuery().in(this);
				query.select('#' + id).boundingClientRect(data => {
					if (!data) return;
					if (data.top - this.viewHeight < 0) {
						this.isLoading = true;
					}
				}).exec()
			},

		}
	}
</script>

<style scoped>
	.gui-img {
		width: 100%;
		height: 100%;
		position: relative;
	}

	.gui-itemImg {
		width: 100%;
		height: 100%;
	}

	.gui-imageLoad {
		position: absolute;
		left: 0;
		top: 0;
		right: 0;
		bottom: 0;
	}

	.gui-loadImg {
		width: 100%;
		height: 100%;
	}

	.showOpacity {
		animation: showOpacity 0.5s;
	}

	@keyframes showOpacity {
		0% {
			opacity: 0;
		}

		50% {
			opacity: .5;
		}

		100% {
			opacity: 1;
		}
	}
</style>
